﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using COFE.Core.Utils;

namespace COFE.Core.Lister
{
    /// <summary>
    /// Take a stream, and pretend it's a FileStream.
    /// </summary>
    public class VirtualFileMemoryStream<T> : MemoryStream
    {
        #region Constructor

        public VirtualFileMemoryStream(Stream origStream, T entity, FileMode mode, FileAccess access, Action<T, Stream> updateProc)
        {
            _entity = entity;
            _mode = mode;
            _access = access;
            switch (_mode)
            {
                case FileMode.Append : 
                case FileMode.Open : 
                case FileMode.OpenOrCreate : 
                case FileMode.Truncate :
                    StreamUtils.CopyStream(origStream, this);                    
                    if (_mode != FileMode.Append)
                        Seek(0, SeekOrigin.Begin);
                    break;
            }
        }

        #endregion

        #region Methods

        public override void Write(byte[] buffer, int offset, int count)
        {
            base.Write(buffer, offset, count);
            _isModified = true;
        }

        public override void WriteByte(byte value)
        {
            base.WriteByte(value);
            _isModified = true;
        }

        public override void Flush()
        {
            base.Flush();            
            Int64 position = Position;
            Seek(0, SeekOrigin.Begin);

            _updateProc(_entity, this);
            _isModified = false;

            Seek(position, SeekOrigin.Begin);
        }

        public override void Close()
        {
            Flush();
            //base.Close();
        }

        #endregion

        #region Data

        private T _entity;
        private bool _isModified = false;
        private FileMode _mode;
        private FileAccess _access;
        private Action<T, Stream> _updateProc = (e, stream) => { };

        #endregion

        #region Public Properties

        public bool IsModified { get { return _isModified; } }
        public override bool CanWrite { get { return _access != FileAccess.Read; } }

        #endregion

    }
}
